home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_03_02 / 3n02018a < prev    next >
Text File  |  1991-12-14  |  17KB  |  541 lines

  1. /* fader.c - main code for fader custom control */
  2.  
  3. #include <windows.h>
  4. #include "fader.h"
  5.  
  6. #define NO_DRAG              0    /* Values of FADER_THUMBSTATE */
  7. #define DRAG                 1
  8.  
  9. #define FADER_THUMB_OFFSET   2    /* Distance in pixels from edge */
  10.  
  11. /* Window extra bytes */
  12. #define FADER_RANGE          0    /* logical range values returned */
  13. #define FADER_VALUE          4    /* Current logical value */
  14. #define FADER_THUMBSTATE     6    /* DRAG or NO_DRAG */
  15. #define FADER_WNDEXTRA       8    /* Total # of window extra bytes */
  16.  
  17. HANDLE hGlobFaderInstance = NULL;
  18. char szGlobControlName[] = "Fader";
  19.  
  20. /* Forward declarations for completeness */
  21.  
  22. static BOOL NEAR PASCAL RegisterControlClass (HANDLE hInstance);
  23. LONG FAR PASCAL FaderWndFn (HWND hWnd, WORD wMsg,
  24.             WORD wParam, LONG lParam);
  25. int GetThumbHeight(int iTotalHeight);
  26. void GetFaderThumbRect(HWND hWnd, LPRECT pRc, LPRECT pThumbRect,
  27.             int iCurPos);
  28. int  XlatPosPhysicalToLogical(LONG lLogRange, int iPhysMax,
  29.             int iPhysMin, int iCurPos);
  30. int  XlatPosLogicalToPhysical(LONG lLogRange, int iPhysMax,
  31.             int iPhysMin, int iLogPos);
  32. static void DrawCaret(HDC hDC, LPRECT lprc);
  33. static void PaintFader(HWND hWnd);
  34.  
  35. /* These are DLL initialization and control functions */
  36.  
  37. BOOL FAR PASCAL LibMain (HANDLE hModule, WORD wDataSeg,
  38.    WORD wHeapSize, LPSTR lpszCmdLine)
  39. {
  40.    hGlobFaderInstance = hModule;
  41.    if (wHeapSize != 0)  /* Moveable DS */
  42.       UnlockData(0);
  43.    return RegisterControlClass(hModule);
  44. }
  45.  
  46.  
  47. int FAR PASCAL WEP (int nSystemExit)
  48. {
  49.    UnregisterClass(szGlobControlName, hGlobFaderInstance);
  50.    return 1;                 /* never fails */
  51. }
  52.  
  53.  
  54. /* This function can be static if you only plan to use it
  55.    in a DLL */
  56.  
  57. BOOL NEAR PASCAL RegisterControlClass (HANDLE hInstance)
  58. {
  59.    WNDCLASS wc;
  60.  
  61.    wc.style         = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
  62.    wc.lpfnWndProc   = FaderWndFn;
  63.    wc.cbClsExtra    = 0;
  64.    wc.cbWndExtra    = FADER_WNDEXTRA;
  65.    wc.hInstance     = hInstance;
  66.    wc.hIcon         = NULL;
  67.    wc.hCursor       = LoadCursor(NULL, IDC_SIZENS);
  68.    wc.hbrBackground = COLOR_WINDOW + 1;
  69.    wc.lpszMenuName  = NULL;
  70.    wc.lpszClassName = szGlobControlName;
  71.    return RegisterClass(&wc);
  72. }
  73.  
  74.  
  75. /* This function is handy for sending the FDRN_... messages
  76.    back to the parent.  Note that FDRN_THUMBTRACK is disabled
  77.    unless FDRS_TRACK is enabled */
  78.  
  79. static LONG NEAR PASCAL NotifyParent (HWND hWnd,
  80.    WORD wNotifyCode)
  81. {
  82.    BOOL bSend=TRUE;
  83.  
  84.    if (wNotifyCode == FDRN_THUMBTRACK)
  85.       bSend = (BOOL) (GetWindowLong(hWnd, GWL_STYLE) & FDRS_TRACK);
  86.  
  87.    if (bSend)
  88.       return SendMessage(GetParent(hWnd), WM_COMMAND,
  89.              GetWindowWord(hWnd, GWW_ID),
  90.              MAKELONG(hWnd, wNotifyCode));
  91.    else
  92.       return 0;
  93. }
  94.  
  95.  
  96. /* This is the main "window function" procedure, it is called
  97.    sometimes by the SDK Dialog box editor */
  98.  
  99. LONG FAR PASCAL FaderWndFn (HWND hWnd, WORD wMsg,
  100.    WORD wParam, LONG lParam)
  101. {
  102.    LONG lResult = 0;
  103.    HDC hDC;
  104.    POINT pt;
  105.    RECT rc;
  106.    int iLogPos;
  107.    int iOldLogPos;
  108.    int iPhyPos;
  109.    int iMaxLog;
  110.    int iMinLog;
  111.    RECT thumb_rect;
  112.    LONG lLogRange;
  113.    int iThumbHalf;
  114.    HANDLE hNewBrush, hOldBrush;
  115.  
  116.    switch (wMsg) {
  117.       case WM_CREATE:
  118.          SendMessage(hWnd, FDRM_SETRANGE, 0, MAKELONG(0, 100));
  119.          SendMessage(hWnd, FDRM_SETLOGVALUE, 0, 0);
  120.          break;
  121.  
  122.       case WM_GETDLGCODE: /* interface query by dialog manager */
  123.          lResult = DLGC_WANTARROWS;
  124.          break;
  125.  
  126.       case WM_PAINT:
  127.          PaintFader(hWnd);
  128.          break;
  129.  
  130.       case WM_SETFOCUS: /* receiving the keyboard focus */
  131.       case WM_KILLFOCUS: /* losing the keyboard focus */
  132.             /* calculate update region */
  133.             GetClientRect(hWnd, &rc);
  134.             iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  135.             GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect,
  136.                iLogPos);
  137.             if (thumb_rect.left == rc.left)
  138.                break;
  139.  
  140.             /* force a repaint */
  141.             hDC = GetDC( hWnd );
  142.             if (hDC) {
  143.                /* define appropriate brush & text colors */
  144.                if (hNewBrush = (HBRUSH)SendMessage( GetParent(hWnd),
  145.                   WM_CTLCOLOR, hDC, MAKELONG(hWnd,CTLCOLOR_BTN) ) )
  146.                   hOldBrush = SelectObject(hDC,hNewBrush);
  147.                else
  148.                   hOldBrush = NULL;
  149.  
  150.                /* draw caret */
  151.                DrawCaret(hDC, (LPRECT)&thumb_rect);
  152.  
  153.                /* restore original brush */
  154.                if ( hNewBrush ) {
  155.                   SelectObject( hDC, hOldBrush );
  156.                   DeleteObject( hNewBrush );
  157.                   }
  158.  
  159.                /* release display context */
  160.                ReleaseDC( hWnd, hDC );
  161.                }
  162.          break;
  163.  
  164.       case WM_KEYDOWN:    /* process virtual key code */
  165.          GetClientRect(hWnd, &rc);
  166.          iLogPos = (int)GetWindowWord(hWnd, FADER_VALUE);
  167.          iOldLogPos = iLogPos;
  168.          lLogRange = GetWindowLong(hWnd, FADER_RANGE);
  169.          iMaxLog = HIWORD(lLogRange);
  170.          iMinLog = LOWORD(lLogRange);
  171.  
  172.          switch (wParam) {
  173.             case VK_HOME : /* home key */
  174.                iLogPos = iMinLog;
  175.                break;
  176.  
  177.             case VK_END : /* end key */
  178.                iLogPos = iMaxLog;
  179.                break;
  180.  
  181.             case VK_LEFT : /* cursor left key */
  182.             case VK_DOWN : /* cursor down key */
  183.                if (iLogPos < iMaxLog)
  184.                   iLogPos++;
  185.                break;
  186.  
  187.             case VK_UP : /* cursor up key */
  188.             case VK_RIGHT : /* cursor right key */
  189.                if (iLogPos > iMinLog)
  190.                   iLogPos--;
  191.                break;
  192.  
  193.             case VK_PRIOR : /* page up key */
  194.                iLogPos -= (iMaxLog - iMinLog) / 8;
  195.                if (iLogPos < iMinLog)
  196.                   iLogPos = iMinLog;
  197.                break;
  198.  
  199.             case VK_NEXT : /* page down key */
  200.                iLogPos += (iMaxLog - iMinLog) / 8;
  201.                if (iLogPos > iMaxLog)
  202.                   iLogPos = iMaxLog;
  203.                break;
  204.  
  205.             default : /* something else */
  206.                break;
  207.             }
  208.  
  209.          if (iLogPos != iOldLogPos) /* did it change? */
  210.             {
  211.             SendMessage(hWnd, FDRM_SETLOGVALUE, iLogPos, 0);
  212.             NotifyParent(hWnd, FDRN_THUMBTRACK);
  213.  
  214.             /* Invalidate old position */
  215.             GetFaderThumbRect(hWnd, (LPRECT)&rc,
  216.                  (LPRECT)&thumb_rect, iOldLogPos);
  217.             InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
  218.  
  219.             /* Invalidate new position */
  220.             GetFaderThumbRect(hWnd, (LPRECT)&rc,
  221.                 (LPRECT)&thumb_rect, iLogPos);
  222.             InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
  223.             }
  224.          break;
  225.  
  226.       case WM_LBUTTONDOWN:
  227.          GetClientRect(hWnd, &rc);
  228.          iLogPos = GetWindowWord(hWnd, FADER_VALUE);
  229.          GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect, iLogPos);
  230.          pt = MAKEPOINT(lParam);
  231.          /* is the mouse in the "hot" rectangle? */
  232.          if ((thumb_rect.top <= pt.y) && (thumb_rect.bottom >= pt.y) &&
  233.             (thumb_rect.left <= pt.x) && (thumb_rect.right  >= pt.x)) {
  234.             SetWindowWord(hWnd, FADER_THUMBSTATE, DRAG);
  235.             hDC = GetDC(hWnd);
  236.             InvertRect(hDC, (LPRECT)&thumb_rect);
  237.             ReleaseDC(hWnd, hDC);
  238.  
  239.             NotifyParent(hWnd, FDRN_THUMBTRACK);
  240.             /* grab focus if necessary */
  241.             if ( GetFocus() != hWnd )
  242.                 SetFocus( hWnd );
  243.             /* Lock mouse on to this window */
  244.             SetCapture(hWnd);
  245.             }
  246.          break;
  247.  
  248.       case WM_MOUSEMOVE:
  249.       case WM_LBUTTONUP:
  250.          /* Nothing to do if not in drag! */
  251.          if ((wMsg == WM_MOUSEMOVE) &&
  252.              (GetWindowWord(hWnd, FADER_THUMBSTATE) != DRAG) ) {
  253.             lResult = DefWindowProc(hWnd, wMsg, wParam, lParam);
  254.             break;
  255.             }
  256.  
  257.